package com.wx.service.impl;


import com.google.common.collect.Lists;
import com.wx.constants.Constants;
import com.wx.domain.dto.AuthUserDto;
import com.wx.domain.vo.DicTreeVo;
import com.wx.entity.SysDict;
import com.wx.exception.BusinessException;
import com.wx.mapper.SysDictMapper;
import com.wx.service.SysDictService;
import com.wx.utils.SnowFlakeUtil;
import com.wx.utils.TreeUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * Title: SysDictService<br>;
 * Description: 数据字典<br>;
 * Copyright: Copyright (c) 2017<br>;
 * Company: <br>;
 *
 * @author xinglinglove1029@163.com<br>
 * 2018/11/21 16:50
 */
@Service
public class SysDictServiceImpl extends BaseServiceImpl<SysDict> implements SysDictService {

    @Resource
    private SysDictMapper sysDictMapper;

    @Override
    public List<DicTreeVo> getDicTree() {
        List<SysDict> dicList = sysDictMapper.selectAllDict();
        Map<String, String> dicMap = dicList.stream().collect(Collectors.toMap(SysDict::getDictCode, SysDict::getDictName));
        List<DicTreeVo> trees = Lists.newArrayList();
        DicTreeVo node = null;
        for (SysDict dic : dicList) {
            node = new DicTreeVo();
            BeanUtils.copyProperties(dic, node);
            node.setDictId(dic.getId());
            node.setDictName(dic.getDictName());
            node.setDictName(dic.getDictName());
            node.setId(dic.getDictCode());
            node.setParentId(dic.getParentCode());
            String parentDicName = dicMap.get(dic.getParentCode());
            node.setParentName(parentDicName);
            node.setDictValue(dic.getDictValue());
            node.setRemarks(dic.getRemarks());
            node.setDisabled(Constants.Sys.DICTIONARY_ROOT.equals(dic.getId()));
            node.setSort(dic.getSort());
            trees.add(node);
        }
        return TreeUtil.bulid(trees, Constants.Sys.ROOT_PARENTID);
    }

    @Override
    public SysDict getDicById(String dicId) {
        return sysDictMapper.selectByPrimaryKey(dicId);
    }

    @Override
    public int deleteDicById(String dicId, AuthUserDto authUserDto) {
        SysDict dictionary = sysDictMapper.selectByPrimaryKey(dicId);
        if (Objects.isNull(dictionary)) {
            throw new BusinessException("参数不合法");
        }
        SysDict children = new SysDict();
        children.setParentCode(dictionary.getDictCode());
        children.setDelFlag(Constants.DELETE_NO);
        List<SysDict> childrenList = sysDictMapper.select(children);
        if (childrenList.size() > 0) {
            throw new BusinessException("该节点下还存在子节点不能删除");
        }
        return sysDictMapper.deleteByPrimaryKey(dicId);
    }

    @Override
    public int modifyDic(SysDict dic, AuthUserDto authUserDto) {
        SysDict queryDic = new SysDict();
        queryDic.setDictCode(dic.getParentCode());
        queryDic.setDelFlag(Constants.DELETE_NO);
        SysDict dictionary = sysDictMapper.selectOne(queryDic);
        if (Objects.isNull(dictionary)) {
            throw new BusinessException("父编码信息不存在");
        }
        SysDict dict = sysDictMapper.selectByPrimaryKey(dic.getId());
        if (Objects.isNull(dict)) {
            throw new BusinessException("数据字典信息不存在");
        }
        dic.setVersion(dict.getVersion() + 1);
        dic.setCreator(authUserDto.getUserName());
        dic.setCreateBy(authUserDto.getUserId());
        dic.setUpdater(authUserDto.getUserName());
        dic.setUpdateBy(authUserDto.getUserId());
        dic.setUpdateDate(new Date());
        return sysDictMapper.updateByPrimaryKeySelective(dic);
    }

    @Override
    public int saveDicInfo(SysDict dic, AuthUserDto authUserDto) {
        SysDict dictionary = sysDictMapper.selectDicByCode(dic.getParentCode());
        if (Objects.isNull(dictionary)) {
            throw new BusinessException("父编码信息不存在");
        }
        SysDict queryDict = new SysDict();
        queryDict.setDictCode(dic.getDictCode());
        queryDict.setDelFlag(Constants.DELETE_NO);
        List<SysDict> dictList = sysDictMapper.select(queryDict);
        if(dictList.size() > 0){
            throw new BusinessException("该code已经存在");
        }
        dic.setId(SnowFlakeUtil.getStringId());
        dic.setLevel(dictionary.getLevel() + 1);
        dic.setCreateDate(new Date());
        dic.setCreator(authUserDto.getUserName());
        dic.setCreateBy(authUserDto.getUserId());
        dic.setUpdater(authUserDto.getUserName());
        dic.setUpdateBy(authUserDto.getUserId());
        return sysDictMapper.insertSelective(dic);
    }

    @Override
    public List<SysDict> getChildrenByCode(String parentCode) {
        SysDict query = new SysDict();
        query.setDelFlag(Constants.DELETE_NO);
        query.setParentCode(parentCode);
        return sysDictMapper.select(query);
    }



    @Override
    public List<SysDict> selectAllDict() {
        return sysDictMapper.selectAllDict();
    }

    @Override
    public List<SysDict> recursionChildrenByParentCode(String parentCode) {
        SysDict query = new SysDict();
        query.setDelFlag(Constants.DELETE_NO);
        List<SysDict> sysDictList = sysDictMapper.select(query);
        List<SysDict> childDictList = Lists.newArrayList();
        List<SysDict> dictList = treeList(childDictList,sysDictList, parentCode);
        List<SysDict> list = sysDictList.stream().filter(f -> f.getDictCode().equals(parentCode)).collect(Collectors.toList());
        dictList.addAll(list);
        return dictList;
    }

    @Override
    public SysDict getDicByCode(String code) {
        return sysDictMapper.selectDicByCode(code);
    }

    private static List<SysDict> treeList(List<SysDict> childDict,List<SysDict> dictList, String pid) {
        for (SysDict dict : dictList) {
            //遍历出父id等于参数的id，add进子节点集合
            if (dict.getParentCode().equals(pid)) {
                //递归遍历下一级
                treeList(childDict,dictList, dict.getDictCode());
                childDict.add(dict);
            }
        }
        return childDict;
    }
}
